package com.joint.web.action.finance;

import com.fz.us.base.bean.BaseEnum;
import com.fz.us.base.bean.Pager;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.joint.base.bean.FlowEnum;
import com.joint.base.entity.*;
import com.joint.base.exception.users.DutyNotExistsException;
import com.joint.base.exception.workflow.PcfgNotExistException;
import com.joint.base.service.TaskFlowService;
import com.joint.base.service.activiti.WorkflowService;
import com.joint.base.util.DataUtil;
import com.joint.core.entity.finance.Expend;
import com.joint.core.entity.manage.Purchase;
import com.joint.core.entity.manage.Reception;
import com.joint.core.service.ExpendService;
import com.joint.core.service.PurchaseService;
import com.joint.core.service.ReceptionService;
import com.joint.web.action.BaseFlowAction;
import net.sf.json.JSONObject;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.ParentPackage;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by ZhuChunXiao on 2017/4/1.
 */
@ParentPackage("finance")
public class AjaxExpendAction extends BaseFlowAction {
    @Resource
    private ExpendService expendService;
    @Resource
    private PurchaseService purchaseService;
    @Resource
    private ReceptionService receptionService;
    @Resource
    private WorkflowService workflowService;
    @Resource
    private TaskFlowService taskFlowService;

    /**
     * 支出类别 1采购支出 2接待支出 3日常支出 4来往支付
     */
    private String type;
    /**
     * 采购申请单
     */
    private String purchaseId;
    private List<Map<String,Object>> purchaseList;
    /**
     * 接待申请单
     */
    private String receptionId;
    private List<Map<String,Object>> receptionList;
    /**
     * 支出内容
     */
    private String expendContent;
    /**
     * 合计
     */
    private String expendNum;
    /**
     * 是否是日常报销或往来支付
     */
    private int isPay;
    /**
     * 是否是产业中心人员
     */
    private int ifCentralStaff;

    private String viewtype;
    private Purchase purchase;
    private Reception reception;
    private Expend expend;
    private Users loginUser;

    public String execute(){
        return "expend";
    }

    public String list(){
        pager = new Pager();
        if (rows <= 0){
            rows = 10;
        }
        pager.setPageSize(rows);
        pager.setPageNumber(page);
        pager.setOrderBy("createDate");
        pager.setOrderType(BaseEnum.OrderType.desc);
        if(StringUtils.isNotEmpty(sidx)&& BaseEnum.OrderType.valueOf(sord)!=null){
            pager.setOrderBy(sidx);
            pager.setOrderType(BaseEnum.OrderType.valueOf(sord));
        }
        Company com = usersService.getCompanyByUser();
        Map<String,Object> params = new HashMap<String,Object>();
        params = getSearchFilterParams(_search,params,filters);
        params.put("company",com);
        params.put("state",BaseEnum.StateEnum.Enable);
        if(StringUtils.isNotEmpty(viewtype)){
            if(viewtype.equals("1")){
                //流转中
                params.put("processState", new FlowEnum.ProcessState []{FlowEnum.ProcessState.Running, FlowEnum.ProcessState.Backed});
                pager= expendService.findByPagerAndLimit(false, "expend", pager, params);
            }else if(viewtype.equals("2")){
                //已归档
                params.put("processState", new FlowEnum.ProcessState []{FlowEnum.ProcessState.Finished});
                pager= expendService.findByPagerAndFinish( "expend", pager, params);
            }
        }else{
            //所有单子
            params.put("processState", new FlowEnum.ProcessState []{FlowEnum.ProcessState.Running, FlowEnum.ProcessState.Backed, FlowEnum.ProcessState.Finished, FlowEnum.ProcessState.Deny});
            pager= expendService.findByPagerAndLimit(true, "expend", pager, params);
        }

        List<Expend> expendList;
        if (pager.getTotalCount() > 0){
            expendList = (List<Expend>) pager.getList();
        }else{
            expendList = new ArrayList<>();
        }
        List<JSONObject> dataRows=new ArrayList<JSONObject>();
        Map<String, Object> data = new HashMap<String, Object>();
        Map<String,Object> rMap;
        String doer="无";
        for(Expend expend : expendList){
            Task task=workflowService.getCurrentTask(expend.getId());
            if(task!=null){
                List<Users> userList=taskFlowService.findUsersByTaskFlow(task.getId());
                for(Users user:userList){
                    doer+=user.getName()+" ";
                }
            }
            rMap = new HashMap<String, Object>();
            rMap.put("id", expend.getId());
            switch (expend.getType()){
                case "1":rMap.put("type","采购支出");break;
                case "2":rMap.put("type","接待支出");break;
                case "3":rMap.put("type","日常支出");break;
                case "4":rMap.put("type","往来支出");break;
            }
            rMap.put("creater", expend.getCreater() != null ? expend.getCreater().getName() : "");
            rMap.put("num", expend.getNum());
            rMap.put("createDate", DataUtil.DateToString(expend.getCreateDate(), "yyyy-MM-dd"));
            rMap.put("doer", doer);
            rMap.put("state", expend.getProcessState().value());
            JSONObject o = JSONObject.fromObject(rMap);
            dataRows.add(o);
        }

        data.put("dataRows",dataRows);
        data.put("page",page);
        data.put("rows",rows);
        long recordsNum = pager.getTotalCount();
        data.put("total",calcPageNum(recordsNum));
        data.put("records", recordsNum);
        return  ajaxJson(JSONObject.fromObject(data).toString());
    }

    public String read(){
        loginUser = usersService.getLoginInfo();
        if(StringUtils.isNotEmpty(keyId)){
            expend=expendService.get(keyId);
            numStatus = workflowService.getNumStatus(keyId, loginUser);
        }
        return "read";
    }

    public String input(){
        Company company = usersService.getCompanyByUser();
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("processState", new FlowEnum.ProcessState[]{FlowEnum.ProcessState.Finished});
        List<Purchase> plist = (List<Purchase>)purchaseService.findByPagerAndCompany(null, null, company, params).getList();
        purchaseList= Lists.newArrayList();
        List<Reception> rlist = (List<Reception>)receptionService.findByPagerAndCompany(null, null, company, params).getList();
        receptionList= Lists.newArrayList();
        Map<String,Object> rmap1;
        Map<String,Object> rmap2;
        if (StringUtils.isNotEmpty(keyId)){
            expend = expendService.get(keyId);
            for(Purchase p:plist){
                rmap1= Maps.newHashMap();
                rmap1.put("id",p.getId());
                rmap1.put("name", "收款方："+p.getToName());
                if(expend.getPurchase()!=null && StringUtils.equals(p.getId(), expend.getPurchase().getId())) {
                    rmap1.put("selected","selected");
                }
                purchaseList.add(rmap1);
            }
            for(Reception r:rlist){
                rmap2= Maps.newHashMap();
                rmap2.put("id",r.getId());
                rmap2.put("name", "来宾姓名："+r.getGuestName());
                if(expend.getReception()!=null && StringUtils.equals(r.getId(), expend.getReception().getId())) {
                    rmap2.put("selected","selected");
                }
                receptionList.add(rmap2);
            }
        }else{
            if(plist.size()>0){
                for(Purchase p:plist){
                    rmap1= Maps.newHashMap();
                    rmap1.put("id", p.getId());
                    rmap1.put("name", "收款方："+p.getToName());
                    rmap1.put("selected","");
                    purchaseList.add(rmap1);
                }
            }
            if(rlist.size()>0){
                for(Reception r:rlist){
                    rmap2= Maps.newHashMap();
                    rmap2.put("id", r.getId());
                    rmap2.put("name", "来宾姓名：" + r.getGuestName());
                    rmap2.put("selected","");
                    receptionList.add(rmap2);
                }
            }
        }
        return "input";
    }

    public void setData(){
        if(StringUtils.isNotEmpty(keyId)){
            expend=expendService.get(keyId);
        }else{
            expend=new Expend();
            expend.setCreater(usersService.getLoginInfo());
        }
        expend.setCompany(usersService.getLoginInfo().getCompany());
        expend.setType(type);
        expend.setContent(expendContent);
        expend.setNum(expendNum);
        if(StringUtils.isNotEmpty(purchaseId)){
            expend.setPurchase(purchaseService.get(purchaseId));
        }
        if(StringUtils.isNotEmpty(receptionId)){
            expend.setReception(receptionService.get(receptionId));
        }
    }

    // 保存
    public String save(){
        setData();
        try {
            if(StringUtils.isNotEmpty(keyId)){
                expendService.update(expend);
            } else {
                Map<String, Object> various = new HashMap<String, Object>();
                various.put("numStatus", 0);
                various.put("curDutyId", curDutyId);
                various.put("initDuty", curDutyId);
                expendService.save(expend, "expend", various);
            }
        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }

        return ajaxHtmlCallback("200", "保存成功！", "操作状态");
    }

    // 提交
    public String commit(){
        setData();
        Map<String, Object> var1 = new HashMap<String, Object>();
        var1.put("numStatus", 0);
        var1.put("curDutyId", curDutyId);
        var1.put("initDuty", curDutyId);
        Map<String, Object> var2 = new HashMap<String, Object>();
        var2.put("numStatus", 1);
        var2.put("curDutyId", curDutyId);

        Set<Duty> dutySet=usersService.getLoginInfo().getDutySet();
        List<String> list=Lists.newArrayList();
        for(Duty duty:dutySet){
            Department dept=duty.getDepartment().getParent()==null?duty.getDepartment():duty.getDepartment().getParent();
            Set<Department> deptSet=dept.getChildren();
            for(Department cdept:deptSet){
                if(cdept.getName().contains("财务科")){
                    Set<Power> powers = cdept.getPowerSet();
                    for(Power power:powers){
                        if(power.getPost().getName().equals("科长")){
                            List<Users> usersList=dutyService.getPersons(cdept,power.getPost());
                            for(Users user:usersList){
                                list.add(user.getId().trim());
                            }
                        }
                    }
                }

            }
        }
        var1.put("approver", list);
        var2.put("approver", list);

        List<String> list2=Lists.newArrayList();
        for(Duty duty:dutySet){
            Department dept=duty.getDepartment().getParent()==null?duty.getDepartment():duty.getDepartment().getParent();
            Set<Power> powers = dept.getPowerSet();
            for(Power power:powers){
                if(power.getPost().getName().equals("总经理")){
                    List<Users> usersList=dutyService.getPersons(dept,power.getPost());
                    for(Users user:usersList){
                        list2.add(user.getId().trim());
                    }
                }
            }
        }
        var1.put("approver1", list2);
        var2.put("approver1", list2);

        try {
            if (StringUtils.isNotEmpty(keyId)) {
                expendService.approve(expend, FlowEnum.ProcessState.Running, var2, curDutyId, comment);
            } else {
                keyId = expendService.commit(expend, "expend", var1, var2, curDutyId);
            }
        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }
        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
    }

    //审批1
    public String approve1(){
        expend = expendService.get(keyId);
        Map<String, Object> var1 = new HashMap<String, Object>();
        var1.put("numStatus", 2);
        var1.put("curDutyId", curDutyId);

        if(StringUtils.isEmpty(comment)){
            comment="";
        }
        try {
            if (StringUtils.isNotEmpty(keyId)) {
                expendService.approve(expend, FlowEnum.ProcessState.Running, var1, curDutyId, comment);
            }
        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }
        catch (Exception e){
            return ajaxHtmlCallback("404", "操作异常，请联系管理员！", "操作状态");
        }
        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
    }

    //审批2
    public String approve2(){
        isPay=0;
        ifCentralStaff=0;
        expend = expendService.get(keyId);
        Map<String, Object> var1 = new HashMap<String, Object>();
        var1.put("curDutyId", curDutyId);

        Set<Duty> dutySet = expend.getCreater().getDutySet();
        for (Duty duty:dutySet){
            if(duty.getDepartment().getParent()!=null){
                if(StringUtils.equals(duty.getDepartment().getParent().getName(),"产业中心")){
                    ifCentralStaff=1;
                    break;
                }
            }
        }
        isPay=expend.getType().equals("1")||expend.getType().equals("2")?1:0;
        if(ifCentralStaff==1){
            var1.put("numStatus", 4);
        }else{
            var1.put("numStatus", 3);
        }
        var1.put("isPay", isPay);
        var1.put("ifCentralStaff", ifCentralStaff);

        if(StringUtils.isEmpty(comment)){
            comment="";
        }
        try {
            if (StringUtils.isNotEmpty(keyId)) {
                if(isPay==1){
                    expendService.approve(expend, FlowEnum.ProcessState.Running, var1, curDutyId, comment);
                }else{
                    expendService.approve(expend, FlowEnum.ProcessState.Finished,var1, curDutyId, comment);
                }

            }
        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }
        catch (Exception e){
            return ajaxHtmlCallback("404", "操作异常，请联系管理员！", "操作状态");
        }
        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
    }

    //审批3
    public String approve3(){
        expend = expendService.get(keyId);
        Map<String, Object> var1 = new HashMap<String, Object>();
        var1.put("numStatus", 4);
        var1.put("curDutyId", curDutyId);

        if(StringUtils.isEmpty(comment)){
            comment="";
        }
        try {
            if (StringUtils.isNotEmpty(keyId)) {
                expendService.approve(expend, FlowEnum.ProcessState.Running, var1, curDutyId, comment);
            }
        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }
        catch (Exception e){
            return ajaxHtmlCallback("404", "操作异常，请联系管理员！", "操作状态");
        }
        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
    }

    //审批4
    public String approve4(){
        expend = expendService.get(keyId);
        Map<String, Object> var1 = new HashMap<String, Object>();
        var1.put("numStatus", 5);
        var1.put("curDutyId", curDutyId);

        if(StringUtils.isEmpty(comment)){
            comment="";
        }
        try {
            if (StringUtils.isNotEmpty(keyId)) {
                expendService.approve(expend, FlowEnum.ProcessState.Finished, var1, curDutyId, comment);
            }
        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }
        catch (Exception e){
            return ajaxHtmlCallback("404", "操作异常，请联系管理员！", "操作状态");
        }
        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
    }

    /**
     * 退回
     * @return
     */
    public String reject() {
        if (StringUtils.isNotEmpty(keyId)) {
            expend = expendService.get(keyId);
            List<ActivityImpl> activityList= workflowService.findAllActivitiesByKey("expend");
            String key=activityList.get(0).getId();
            System.out.println("Activity key:"+key);
            if(StringUtils.isEmpty(comment)) comment="";
            expendService.reject(expend, key, numStatus, comment, curDutyId);
        }
        return ajaxHtmlCallback("200", "退回成功！", "操作状态");
    }

    /**
     * 否决
     * @return
     */
    public String deny() {
        if (StringUtils.isNotEmpty(keyId)) {
            expend = expendService.get(keyId);
            List<ActivityImpl> activityList= workflowService.findAllActivitiesByKey("expend");
            String key= activityList.get(activityList.size()-1).getId();
            if(StringUtils.isEmpty(comment)){
                comment="";
            }
            expendService.deny(expend, key, comment, curDutyId);
        }
        return ajaxHtmlCallback("200", "否决成功！", "操作状态");
    }



    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getPurchaseId() {
        return purchaseId;
    }

    public void setPurchaseId(String purchaseId) {
        this.purchaseId = purchaseId;
    }

    public String getReceptionId() {
        return receptionId;
    }

    public void setReceptionId(String receptionId) {
        this.receptionId = receptionId;
    }

    public String getExpendContent() {
        return expendContent;
    }

    public void setExpendContent(String expendContent) {
        this.expendContent = expendContent;
    }

    public String getExpendNum() {
        return expendNum;
    }

    public void setExpendNum(String expendNum) {
        this.expendNum = expendNum;
    }

    public int getIsPay() {
        return isPay;
    }

    public void setIsPay(int isPay) {
        this.isPay = isPay;
    }

    public int getIfCentralStaff() {
        return ifCentralStaff;
    }

    public void setIfCentralStaff(int ifCentralStaff) {
        this.ifCentralStaff = ifCentralStaff;
    }

    public String getViewtype() {
        return viewtype;
    }

    public void setViewtype(String viewtype) {
        this.viewtype = viewtype;
    }

    public Purchase getPurchase() {
        return purchase;
    }

    public void setPurchase(Purchase purchase) {
        this.purchase = purchase;
    }

    public Reception getReception() {
        return reception;
    }

    public void setReception(Reception reception) {
        this.reception = reception;
    }

    public Expend getExpend() {
        return expend;
    }

    public void setExpend(Expend expend) {
        this.expend = expend;
    }

    public List<Map<String, Object>> getPurchaseList() {
        return purchaseList;
    }

    public void setPurchaseList(List<Map<String, Object>> purchaseList) {
        this.purchaseList = purchaseList;
    }

    public List<Map<String, Object>> getReceptionList() {
        return receptionList;
    }

    public void setReceptionList(List<Map<String, Object>> receptionList) {
        this.receptionList = receptionList;
    }

    public Users getLoginUser() {
        return loginUser;
    }

    public void setLoginUser(Users loginUser) {
        this.loginUser = loginUser;
    }
}
